package cn.itcast.nems.studentrecord.web.controller.o;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.EnumUtil;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.enumeration.NemsErrorBodyEnum;
import cn.itcast.nems.oldems.dto.StudentClazzInfoDTO;
import cn.itcast.nems.oldems.dto.StudentClazzStatisticsInfoDTO;
import cn.itcast.nems.oldems.dto.StudentInfoDTO;
import cn.itcast.nems.studentrecord.dto.StudentRecordInfoDTO;
import cn.itcast.nems.studentrecord.dto.StudentRecordInfoQueryDTO;
import cn.itcast.nems.studentrecord.dto.StudentRecordRefundInfoDTO;
import cn.itcast.nems.studentrecord.dto.odto.EmsClassDTO;
import cn.itcast.nems.studentrecord.dto.odto.StudentAndClassInfoDTO;
import cn.itcast.nems.studentrecord.dto.odto.StudentBasicDTO;
import cn.itcast.nems.studentrecord.enumeration.StudentRecordStateEnum;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordInfoService;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordOService;
import cn.itcast.nems.studentrecord.web.vo.form.StudentRecordMergedCallBack;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 学籍相关接口
 * </p>
 *
 * @author zhouwei
 * @since 2024/3/12 4:41 PM
 **/
@RestController
@RequestMapping("/o")
@RequiredArgsConstructor
@Slf4j
public class OStudentRecordController {
    private final StudentRecordInfoService studentRecordInfoService;
    private final StudentRecordOService studentRecordOService;

    @PostMapping("/student/record/merged/callback")
    public ResponseEntity<Boolean> studentRecordMergedCallBack(
            HttpServletRequest request,
            @RequestBody StudentRecordMergedCallBack callBack
    ) {
        String employee;
        var account = AccountHolder.getAccount();
        if (account.isPresent()) {
            employee = account.get();
        } else {
            employee = request.getHeader("Principal-Email");
        }
        if (!StringUtils.hasText(employee)) {
            employee = "";
        }
        return ResponseEntity.ok(studentRecordOService.studentRecordMergedCallBack(
                        callBack.getFromStudentId(),
                        callBack.getToStudentId(),
                        employee
                )
        );
    }

    /**
     * <p>
     * 根据班级ID查询学籍列表
     * </p>
     *
     * @author zhouwei
     * @since 2024/4/15 3:26 PM
     **/
    @GetMapping("/clazz/{clazzId}/student/record")
    public ResponseEntity<List<StudentRecordInfoDTO>> queryStudentRecordListByClazzId(@PathVariable("clazzId") Integer clazzId,
                                                                                      @RequestParam(value = "state", defaultValue = "") String state,
                                                                                      @RequestParam(value = "settlement_reason", defaultValue = "") String settlementReason) {
        Assert.notNull(clazzId, "班级ID不能为空");
        log.info("【根据班级ID查询学籍列表】请求参数 clazzId：{}，state：{}，settlementReason：{}" ,clazzId ,state,settlementReason );
        StudentRecordInfoQueryDTO queryDTO = new StudentRecordInfoQueryDTO();
        queryDTO.setClazzId(clazzId);
        Assert.isTrue(!StringUtils.hasText(state) || EnumUtil.contains(StudentRecordStateEnum.class, state), "学籍状态值不正确");
        queryDTO.setState(state);
        Set<String> settlementReasons = StringUtils.hasText(settlementReason) ? Arrays.stream(settlementReason.split(",")).collect(Collectors.toSet()) : null;
        queryDTO.setSettlementReasonSet(settlementReasons);
        List<StudentRecordInfoDTO> list = studentRecordInfoService.queryStudentRecordListByClazzId(queryDTO);
        return ResponseEntity.ok().body(list);
    }

    /**
     * <p>
     * 根据学员ID查询学员详情
     * </p>
     *
     * @param ids 学员ID ，支持多个
     * @author zhouwei
     * @since 2024/3/13 9:21 AM
     **/
    @GetMapping("/student")
    public ResponseEntity<List<StudentInfoDTO>> queryStudentListByIds(@RequestParam(value = "ids", defaultValue = "") String ids,
                                                                      @RequestParam(value = "keyword", defaultValue = "") String keyword) {
        Assert.notNull(StringUtils.hasText(ids) || StringUtils.hasText(keyword), BizExceptionProducer.produce(NemsErrorBodyEnum.PARAM_EMPTY, "[学员ID]和[keyword]不能同时为空"));
        log.info("【根据学号获取学员的学籍信息】请求参数 ids：{}，keyword：{}" ,ids ,keyword );
        Set<Integer> studentIds = StringUtils.hasText(ids) ? Arrays.stream(ids.split(",")).map(Integer::valueOf).collect(Collectors.toSet()) : null;
        List<StudentInfoDTO> list = studentRecordInfoService.queryStudentRecordListByStudentIds(studentIds, keyword);
        return ResponseEntity.ok().body(list);
    }

    /**
     * <p>
     * 根据学号获取学员的学籍信息
     * </p>
     *
     * @author zhouwei
     * @since 2024/3/12 7:21 PM
     **/
    @GetMapping("/student/recorder")
    public ResponseEntity<List<StudentClazzInfoDTO>> queryClazzListByStudentNos(@RequestParam(value = "student_nos", defaultValue = "") String nos) {
        Assert.notNull(nos, BizExceptionProducer.produce(NemsErrorBodyEnum.PARAM_EMPTY, "学号不能为空"));
        log.info("【根据学号获取学员的学籍信息】请求参数 nos：{}" ,nos);
        Set<String> studentNos = StringUtils.hasText(nos) ? Arrays.stream(nos.split(",")).collect(Collectors.toSet()) : null;
        List<StudentClazzInfoDTO> list = studentRecordInfoService.queryClazzListByStudentNos(studentNos);
        return ResponseEntity.ok().body(list);
    }

    /**
     * <p>
     * 获取班级里的学籍统计信息
     * </p>
     *
     * @author zhouwei
     * @since 2024/3/13 11:41 AM
     **/
    @GetMapping("/student/record/stat/{clazzId}")
    public ResponseEntity<StudentClazzStatisticsInfoDTO> statisticsByClassId(@PathVariable(value = "clazzId") Integer clazzId) {
        Assert.notNull(clazzId, "班级ID不能为空");
        log.info("【获取班级里的学籍统计信息】请求参数 class_id：{}" ,clazzId);
        StudentClazzStatisticsInfoDTO statisticsInfoDTO = studentRecordInfoService.statisticsByClassId(clazzId);
        return ResponseEntity.ok().body(statisticsInfoDTO);
    }

    /**
     * <p>
     * 查询指定学籍的退学凭单详情
     * </p>
     *
     * @param studentRecordId 学籍ID
     * @author zhouwei
     * @since 2024/3/18 11:34 AM
     **/
    @GetMapping("/student/record/{studentRecordId}/dropout")
    public ResponseEntity<StudentRecordRefundInfoDTO> queryRefundJournalByStudentRecordId(@PathVariable(value = "studentRecordId") String studentRecordId) {
        Assert.notNull(studentRecordId, "学籍ID不能为空");
        StudentRecordRefundInfoDTO recordRefundInfoDTO = studentRecordInfoService.queryRefundJournalByStudentRecordId(studentRecordId);
        return ResponseEntity.ok().body(recordRefundInfoDTO);
    }


    // 2024/3/13 11:41 AM
    // '/a' is mean (ems) adapter
    // and cross service permission filter

    @GetMapping("/student/a/inner/{accountId}/basic")
    public ResponseEntity<StudentBasicDTO> basic(@PathVariable("accountId") String accountId) {
        final StudentBasicDTO studentBasic = studentRecordOService.getStudentBasic(accountId);
        return ResponseEntity.ok(studentBasic);
    }

    @GetMapping("/student/a/inner/{accountId}/classes")
    public ResponseEntity<List<EmsClassDTO>> queryStudentClasses(
            @PathVariable("accountId") String accountID,
            @RequestParam(required = false) Boolean pending,
            @RequestParam(required = false) Boolean deleted,
            @RequestParam(required = false) Boolean graduation
    ) {
        var classes = studentRecordOService.queryStudentClasses(
                accountID, pending, deleted, graduation
        );
        return ResponseEntity.ok(classes);
    }

    @GetMapping("/teacher/a/inner/classes")
    public ResponseEntity<List<EmsClassDTO>> findTeacherInnerClasses(@RequestParam String email, @RequestParam Boolean pending) {
        return ResponseEntity.ok(studentRecordOService.findTeacherInnerClasses(email, pending));
    }

    @GetMapping("/student/account/{accountId}/classes")
    public ResponseEntity<StudentAndClassInfoDTO> moreInfo(
            @PathVariable String accountId,
            @RequestParam(value = "pending", required = false, defaultValue = "false") boolean includePending,
            @RequestParam(value = "deleted", required = false, defaultValue = "false") boolean includeDeleted,
            @RequestParam(value = "graduation", required = false, defaultValue = "false") boolean isGraduation
    ) {
        return ResponseEntity.ok(studentRecordOService.moreInfo(accountId, includePending, includeDeleted, isGraduation));
    }

}
